#!/bin/bash

# 脚本名称: elk_deploy.sh
# 功能描述: 在CentOS 7.9系统中自动部署ELK(Elasticsearch, Logstash, Kibana)堆栈
# 使用方法: sudo bash elk_deploy.sh [选项]
# 选项:
#   --selinux-permissive  自动将SELinux设置为宽容模式（适用于自动化部署）
# 环境变量:
#   AUTO_SELINUX_PERMISSIVE=true  自动将SELinux设置为宽容模式
# 数据目录: /data

# 检查是否以root权限运行
if [ "$(id -u)" -ne 0 ]; then
    echo "错误: 请使用root权限运行此脚本"
    exit 1
fi

# 日志文件路径
LOG_FILE="/var/log/elk_deploy.log"

# 记录日志函数
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

# 检查命令执行结果
check_result() {
    if [ $? -ne 0 ]; then
        log "错误: $1 失败"
        # 如果提供了第二个参数且为noexit，则不退出脚本
        if [ -z "$2" ] || [ "$2" != "noexit" ]; then
            exit 1
        fi
        return 1
    else
        log "成功: $1 完成"
        return 0
    fi
}

# 创建数据目录
setup_data_dirs() {
    log "创建ELK数据目录..."
    
    # 创建Elasticsearch数据目录
    mkdir -p /data/elasticsearch
    chown -R elasticsearch:elasticsearch /data/elasticsearch
    chmod -R 755 /data/elasticsearch
    
    # 创建Logstash数据目录
    mkdir -p /data/logstash
    chown -R logstash:logstash /data/logstash
    chmod -R 755 /data/logstash
    
    # 创建Kibana数据目录
    mkdir -p /data/kibana
    chown -R kibana:kibana /data/kibana
    chmod -R 755 /data/kibana
    
    # 创建Filebeat数据目录
    mkdir -p /data/filebeat
    chmod -R 755 /data/filebeat
    
    check_result "创建数据目录"
}

# 安装Java环境
install_java() {
    log "检查并安装Java环境..."
    
    if type -p java &>/dev/null; then
        java_version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}')
        log "检测到Java已安装，版本: $java_version"
    else
        log "安装OpenJDK 11..."
        yum install -y java-11-openjdk-devel
        check_result "安装Java"
        
        java_version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}')
        log "Java安装完成，版本: $java_version"
    fi
}

# 安装Elasticsearch
install_elasticsearch() {
    log "安装Elasticsearch..."
    
    # 添加Elasticsearch仓库
    log "添加Elasticsearch仓库..."
    rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    
    cat > /etc/yum.repos.d/elasticsearch.repo << EOF
[elasticsearch]
name=Elasticsearch repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF
    
    check_result "添加Elasticsearch仓库"
    
    # 安装Elasticsearch
    log "安装Elasticsearch包..."
    yum install -y elasticsearch
    check_result "安装Elasticsearch"
    
    # 配置系统参数
    log "配置系统参数..."
    # 增加最大文件描述符限制
    mkdir -p /etc/systemd/system/elasticsearch.service.d/
    cat > /etc/systemd/system/elasticsearch.service.d/override.conf << EOF
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65535
LimitNPROC=4096
EOF
    
    # 设置系统参数
    sysctl -w vm.max_map_count=262144 &>> $LOG_FILE
    echo "vm.max_map_count=262144" >> /etc/sysctl.conf
    
    # 配置Elasticsearch
    log "配置Elasticsearch..."
    # 备份原配置文件
    cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.bak
    cp /etc/elasticsearch/jvm.options /etc/elasticsearch/jvm.options.bak
    
    # 修改JVM配置
    log "配置Elasticsearch JVM内存..."
    # 获取系统内存总量(MB)
    total_mem=$(free -m | grep Mem | awk '{print $2}')
    # 计算Elasticsearch可用内存(系统内存的一半，但不超过31GB)
    es_mem=$(($total_mem / 2))
    if [ $es_mem -gt 31744 ]; then
        es_mem=31744
    fi
    # 设置JVM堆大小
    cat > /etc/elasticsearch/jvm.options.d/heap.options << EOF
-Xms${es_mem}m
-Xmx${es_mem}m
EOF
    
    # 修改配置文件
    cat > /etc/elasticsearch/elasticsearch.yml << EOF
# ======================== Elasticsearch Configuration =========================
cluster.name: elk-cluster
node.name: node-1
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["127.0.0.1"]
cluster.initial_master_nodes: ["node-1"]

# 性能优化设置
bootstrap.memory_lock: true
thread_pool.write.queue_size: 1000
EOF
    
    check_result "配置Elasticsearch"
    
    # 确保数据目录权限正确
    log "确保数据目录权限正确..."
    chown -R elasticsearch:elasticsearch /data/elasticsearch
    chmod -R 755 /data/elasticsearch
    
    # 启动Elasticsearch服务
    log "启动Elasticsearch服务..."
    systemctl daemon-reload
    systemctl enable elasticsearch
    
    # 尝试启动服务并处理可能的错误
    if ! systemctl start elasticsearch; then
        log "警告: Elasticsearch启动失败，检查日志..."
        log "Elasticsearch日志内容:"
        tail -n 50 /var/log/elasticsearch/elk-cluster.log &>> $LOG_FILE
        log "系统日志内容:"
        journalctl -u elasticsearch --no-pager -n 50 &>> $LOG_FILE
        
        log "尝试修复常见问题..."
        # 检查是否是内存锁定问题
        if grep -q "memory locking requested" /var/log/elasticsearch/elk-cluster.log; then
            log "检测到内存锁定问题，禁用内存锁定..."
            sed -i 's/bootstrap.memory_lock: true/bootstrap.memory_lock: false/' /etc/elasticsearch/elasticsearch.yml
            systemctl daemon-reload
            systemctl restart elasticsearch
        fi
        
        # 再次检查服务状态
        if ! systemctl is-active elasticsearch &>/dev/null; then
            log "错误: 无法启动Elasticsearch服务，请检查日志获取详细信息"
            log "提示: 可能需要手动调整系统参数或Elasticsearch配置"
            exit 1
        fi
    fi
    
    log "成功: 启动Elasticsearch服务 完成"
    
    # 等待Elasticsearch启动
    log "等待Elasticsearch启动..."
    sleep 30
    
    # 验证Elasticsearch是否正常运行
    log "验证Elasticsearch..."
    for i in {1..5}; do
        if curl -s -X GET "localhost:9200/" &>> $LOG_FILE; then
            log "成功: Elasticsearch已正常运行"
            break
        else
            if [ $i -eq 5 ]; then
                log "错误: 验证Elasticsearch失败，但服务似乎已启动，继续部署"
            else
                log "等待Elasticsearch响应...(尝试 $i/5)"
                sleep 10
            fi
        fi
    done
}

# 安装Logstash
install_logstash() {
    log "安装Logstash..."
    
    # 安装Logstash
    log "安装Logstash包..."
    yum install -y logstash
    check_result "安装Logstash"
    
    # 配置Logstash
    log "配置Logstash..."
    # 创建配置文件
    cat > /etc/logstash/conf.d/logstash.conf << EOF
input {
  beats {
    port => 5044
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "logstash-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}
EOF
    
    # 设置数据目录
    mkdir -p /etc/logstash/settings
    cat > /etc/logstash/settings/logstash.yml << EOF
path.data: /data/logstash
EOF
    
    check_result "配置Logstash"
    
    # 启动Logstash服务
    log "启动Logstash服务..."
    systemctl enable logstash
    systemctl start logstash
    check_result "启动Logstash服务"
}

# 安装Kibana
install_kibana() {
    log "安装Kibana..."
    
    # 安装Kibana
    log "安装Kibana包..."
    yum install -y kibana
    check_result "安装Kibana"
    
    # 配置Kibana
    log "配置Kibana..."
    # 备份原配置文件
    cp /etc/kibana/kibana.yml /etc/kibana/kibana.yml.bak
    
    # 修改配置文件
    cat > /etc/kibana/kibana.yml << EOF
# ======================== Kibana Configuration =========================
server.host: "0.0.0.0"
server.port: 5601
elasticsearch.hosts: ["http://localhost:9200"]
path.data: /data/kibana
i18n.locale: "zh-CN"
EOF
    
    check_result "配置Kibana"
    
    # 确保数据目录权限正确
    log "确保Kibana数据目录权限正确..."
    mkdir -p /data/kibana
    chown -R kibana:kibana /data/kibana
    chmod -R 755 /data/kibana
    
    # 等待Elasticsearch完全启动
    log "等待Elasticsearch完全启动..."
    for i in {1..10}; do
        if curl -s "http://localhost:9200" > /dev/null; then
            log "Elasticsearch已准备就绪，继续安装Kibana"
            break
        else
            log "等待Elasticsearch响应...(尝试 $i/10)"
            sleep 10
        fi
        
        if [ $i -eq 10 ]; then
            log "警告: 无法连接到Elasticsearch，但将继续安装Kibana"
        fi
    done
    
    # 启动Kibana服务
    log "启动Kibana服务..."
    systemctl enable kibana
    systemctl start kibana
    
    # 给Kibana更多的启动时间
    log "等待Kibana启动(这可能需要一分钟)..."
    sleep 60
    
    # 验证Kibana是否正常运行
    log "验证Kibana..."
    for i in {1..3}; do
        if curl -s -o /dev/null -w "%{http_code}" "http://localhost:5601/app/home" | grep -q "200\|302"; then
            log "成功: Kibana已正常运行"
            break
        else
            if [ $i -eq 3 ]; then
                log "警告: 验证Kibana失败，但服务似乎已启动，继续部署"
            else
                log "等待Kibana响应...(尝试 $i/3)"
                sleep 20
            fi
        fi
    done
}

# 安装Filebeat
install_filebeat() {
    log "安装Filebeat..."
    
    # 安装Filebeat
    log "安装Filebeat包..."
    yum install -y filebeat
    check_result "安装Filebeat"
    
    # 配置Filebeat
    log "配置Filebeat..."
    # 备份原配置文件
    cp /etc/filebeat/filebeat.yml /etc/filebeat/filebeat.yml.bak
    
    # 修改配置文件
    cat > /etc/filebeat/filebeat.yml << EOF
# ======================== Filebeat Configuration =========================
filebeat.inputs:
- type: log
  paths:
    - /var/log/*.log

output.logstash:
  hosts: ["localhost:5044"]

path.data: /data/filebeat
path.logs: /var/log/filebeat
EOF
    
    check_result "配置Filebeat"
    
    # 启动Filebeat服务
    log "启动Filebeat服务..."
    systemctl enable filebeat
    systemctl start filebeat
    check_result "启动Filebeat服务"
}

# 诊断Elasticsearch问题
diagnose_elasticsearch() {
    log "诊断Elasticsearch问题..."
    
    # 检查Elasticsearch服务状态
    es_status=$(systemctl is-active elasticsearch)
    log "Elasticsearch服务状态: $es_status"
    
    if [ "$es_status" != "active" ]; then
        log "Elasticsearch服务未正常运行，开始诊断..."
        
        # 检查日志文件
        if [ -f "/var/log/elasticsearch/elk-cluster.log" ]; then
            log "Elasticsearch日志内容(最后20行):"
            tail -n 20 /var/log/elasticsearch/elk-cluster.log &>> $LOG_FILE
        else
            log "警告: 找不到Elasticsearch日志文件"
        fi
        
        # 检查系统资源
        log "系统资源使用情况:"
        free -h &>> $LOG_FILE
        df -h &>> $LOG_FILE
        
        # 检查JVM配置
        log "JVM配置:"
        if [ -f "/etc/elasticsearch/jvm.options" ]; then
            grep -E "^-Xms|-Xmx" /etc/elasticsearch/jvm.options* &>> $LOG_FILE
        fi
        
        # 检查系统限制
        log "系统限制:"
        ulimit -a &>> $LOG_FILE
        sysctl vm.max_map_count &>> $LOG_FILE
        
        # 提供修复建议
        log "可能的解决方案:"
        log "1. 检查系统内存是否足够(至少4GB可用)"
        log "2. 确保vm.max_map_count至少为262144: sudo sysctl -w vm.max_map_count=262144"
        log "3. 检查数据目录权限: chown -R elasticsearch:elasticsearch /data/elasticsearch"
        log "4. 调整JVM堆大小: 编辑/etc/elasticsearch/jvm.options.d/heap.options"
        log "5. 检查磁盘空间是否充足"
    else
        # 如果服务运行但无法访问API
        if ! curl -s "localhost:9200" &>/dev/null; then
            log "Elasticsearch服务运行中但API不可访问，可能原因:"
            log "1. 防火墙阻止了9200端口"
            log "2. Elasticsearch仍在启动中"
            log "3. 绑定地址配置不正确"
            
            # 检查网络配置
            netstat -tlpn | grep 9200 &>> $LOG_FILE
            grep "network.host\|http.port" /etc/elasticsearch/elasticsearch.yml &>> $LOG_FILE
        fi
    fi
}

# 验证ELK部署
verify_elk() {
    log "验证ELK部署..."
    
    # 检查各服务状态
    log "检查服务状态:"
    es_status=$(systemctl is-active elasticsearch)
    ls_status=$(systemctl is-active logstash)
    kb_status=$(systemctl is-active kibana)
    fb_status=$(systemctl is-active filebeat)
    
    log "Elasticsearch状态: $es_status"
    log "Logstash状态: $ls_status"
    log "Kibana状态: $kb_status"
    log "Filebeat状态: $fb_status"
    
    # 获取服务器IP地址
    SERVER_IP=$(hostname -I | awk '{print $1}')
    
    # 检查是否有服务未正常运行
    if [ "$es_status" != "active" ] || [ "$ls_status" != "active" ] || [ "$kb_status" != "active" ] || [ "$fb_status" != "active" ]; then
        log "警告: 部分服务未正常运行"
        
        # 如果Elasticsearch未运行，诊断问题
        if [ "$es_status" != "active" ]; then
            diagnose_elasticsearch
        fi
        
        log "部署完成，但有服务未正常运行，请查看日志获取详细信息"
    else
        log "所有服务正常运行!"
    fi
    
    log "ELK部署完成!"
    log "Elasticsearch可通过 http://${SERVER_IP}:9200 访问"
    log "Kibana可通过 http://${SERVER_IP}:5601 访问"
    log "请在Kibana中创建索引模式(如logstash-*)以查看日志数据"
    
    # 提供故障排除提示
    log "如遇问题，可查看以下日志:"
    log "- Elasticsearch: /var/log/elasticsearch/elk-cluster.log"
    log "- Logstash: /var/log/logstash/logstash-plain.log"
    log "- Kibana: /var/log/kibana/kibana.log"
    log "- Filebeat: /var/log/filebeat/filebeat"
    log "- 系统日志: journalctl -xe"
}

# 配置防火墙
configure_firewall() {
    log "配置防火墙..."
    
    # 检查防火墙是否运行
    if systemctl is-active firewalld &>/dev/null; then
        log "配置防火墙规则..."
        
        # 开放Elasticsearch端口
        firewall-cmd --permanent --add-port=9200/tcp
        firewall-cmd --permanent --add-port=9300/tcp
        
        # 开放Kibana端口
        firewall-cmd --permanent --add-port=5601/tcp
        
        # 开放Logstash端口
        firewall-cmd --permanent --add-port=5044/tcp
        
        # 重新加载防火墙配置
        firewall-cmd --reload
        
        log "防火墙配置完成"
    else
        log "防火墙未运行，跳过防火墙配置"
    fi
}

# 检查系统要求
check_system_requirements() {
    log "检查系统要求..."
    
    # 检查系统内存
    total_mem=$(free -m | grep Mem | awk '{print $2}')
    log "系统总内存: ${total_mem}MB"
    
    if [ $total_mem -lt 4096 ]; then
        log "警告: 系统内存小于4GB，Elasticsearch可能无法正常运行"
        log "建议: 至少需要4GB内存才能流畅运行ELK堆栈"
    fi
    
    # 检查可用磁盘空间
    available_space=$(df -m /data | awk 'NR==2 {print $4}')
    log "/data目录可用空间: ${available_space}MB"
    
    if [ $available_space -lt 10240 ]; then
        log "警告: /data目录可用空间小于10GB，建议至少预留10GB空间用于ELK数据存储"
    fi
    
    # 检查最大文件描述符数量
    max_file_descriptors=$(ulimit -n)
    log "最大文件描述符数量: $max_file_descriptors"
    
    if [ $max_file_descriptors -lt 65536 ]; then
        log "调整最大文件描述符数量..."
        ulimit -n 65536 &>/dev/null || log "警告: 无法设置最大文件描述符数量，请手动设置"
    fi
    
    # 检查最大虚拟内存映射数
    vm_max_map_count=$(sysctl -n vm.max_map_count)
    log "最大虚拟内存映射数: $vm_max_map_count"
    
    if [ $vm_max_map_count -lt 262144 ]; then
        log "调整最大虚拟内存映射数..."
        sysctl -w vm.max_map_count=262144 &>> $LOG_FILE
        echo "vm.max_map_count=262144" >> /etc/sysctl.conf
    fi
    
    # 检查SELinux状态
    if command -v getenforce &>/dev/null; then
        selinux_status=$(getenforce)
        log "SELinux状态: $selinux_status"
        
        if [ "$selinux_status" = "Enforcing" ]; then
            log "SELinux处于强制模式，可能会影响Elasticsearch运行"
            log "配置SELinux策略..."
            
            # 检查是否安装了policycoreutils-python
            if ! rpm -q policycoreutils-python &>/dev/null; then
                log "安装policycoreutils-python..."
                yum install -y policycoreutils-python
            fi
            
            # 为Elasticsearch配置SELinux策略
            log "为Elasticsearch配置SELinux策略..."
            
            # 尝试为Elasticsearch端口配置SELinux策略
            if ! semanage port -a -t http_port_t -p tcp 9200 &>/dev/null; then
                log "警告: 无法为Elasticsearch端口配置SELinux策略"
                # 检查端口是否已经配置
                if semanage port -l | grep -q "http_port_t.*9200"; then
                    log "端口9200已经配置为http_port_t类型，继续执行"
                else
                    # 尝试使用其他端口类型
                    # 首先检查elasticsearch_port_t类型是否存在
                    if semanage fcontext -l | grep -q elasticsearch_port_t; then
                        semanage port -a -t elasticsearch_port_t -p tcp 9200 &>/dev/null || \
                        semanage port -m -t http_port_t -p tcp 9200 &>/dev/null || \
                        log "错误: 所有尝试配置端口9200的方法均失败"
                    else
                        # 如果elasticsearch_port_t不存在，尝试使用其他通用类型
                        semanage port -m -t http_port_t -p tcp 9200 &>/dev/null || \
                        semanage port -a -t unreserved_port_t -p tcp 9200 &>/dev/null || \
                        log "错误: 所有尝试配置端口9200的方法均失败"
                    fi
                fi
            fi
            
            # 尝试为Elasticsearch传输端口配置SELinux策略
            if ! semanage port -a -t http_port_t -p tcp 9300 &>/dev/null; then
                log "警告: 无法为Elasticsearch传输端口配置SELinux策略"
                # 检查端口是否已经配置
                if semanage port -l | grep -q "http_port_t.*9300"; then
                    log "端口9300已经配置为http_port_t类型，继续执行"
                else
                    # 尝试使用其他端口类型
                    # 首先检查elasticsearch_port_t类型是否存在
                    if semanage fcontext -l | grep -q elasticsearch_port_t; then
                        semanage port -a -t elasticsearch_port_t -p tcp 9300 &>/dev/null || \
                        semanage port -m -t http_port_t -p tcp 9300 &>/dev/null || \
                        log "错误: 所有尝试配置端口9300的方法均失败"
                    else
                        # 如果elasticsearch_port_t不存在，尝试使用其他通用类型
                        semanage port -m -t http_port_t -p tcp 9300 &>/dev/null || \
                        semanage port -a -t unreserved_port_t -p tcp 9300 &>/dev/null || \
                        log "错误: 所有尝试配置端口9300的方法均失败"
                    fi
                fi
            fi
            
            # 为数据目录设置正确的上下文
            log "为数据目录设置SELinux上下文..."
            if ! semanage fcontext -a -t elasticsearch_data_t "/data/elasticsearch(/.*)?" &>/dev/null; then
                log "警告: 无法为Elasticsearch数据目录配置SELinux上下文"
                # 检查elasticsearch_data_t类型是否存在
                if semanage fcontext -l | grep -q elasticsearch_data_t; then
                    log "elasticsearch_data_t类型存在，但无法应用到目录，尝试其他方法"
                fi
                
                # 尝试使用其他常见数据目录类型
                log "尝试使用其他SELinux类型..."
                if semanage fcontext -a -t var_lib_t "/data/elasticsearch(/.*)?" &>/dev/null; then
                    log "成功: 使用var_lib_t类型为数据目录配置SELinux上下文"
                elif semanage fcontext -a -t httpd_sys_content_t "/data/elasticsearch(/.*)?" &>/dev/null; then
                    log "成功: 使用httpd_sys_content_t类型为数据目录配置SELinux上下文"
                elif semanage fcontext -a -t default_t "/data/elasticsearch(/.*)?" &>/dev/null; then
                    log "成功: 使用default_t类型为数据目录配置SELinux上下文"
                else
                    log "错误: 无法为数据目录设置任何SELinux上下文"
                    log "尝试手动设置目录权限..."
                    chmod -R 777 /data/elasticsearch &>/dev/null && \
                    log "已临时设置目录为最大权限，但这不是安全的长期解决方案"
                fi
            fi
            
            # 应用上下文
            restorecon -Rv /data/elasticsearch &>/dev/null
            
            # 检查是否有任何SELinux配置失败
            if grep -q "错误: 所有尝试配置端口" $LOG_FILE || grep -q "错误: 无法为数据目录设置任何SELinux上下文" $LOG_FILE; then
                log "SELinux配置存在问题，提供替代方案:"
                log "1. 您可以临时设置SELinux为宽容模式: 'sudo setenforce 0'"
                log "2. 或永久修改SELinux配置: 编辑/etc/selinux/config文件，将SELINUX=enforcing改为SELINUX=permissive"
                log "3. 或创建自定义SELinux策略模块"
                
                # 检查是否有AUTO_SELINUX_PERMISSIVE环境变量或命令行参数
                if [ "$AUTO_SELINUX_PERMISSIVE" = "true" ] || [ "$1" = "--selinux-permissive" ]; then
                    log "自动设置SELinux为宽容模式..."
                    setenforce 0
                    log "SELinux已设置为宽容模式，安装将继续"
                    log "注意: 系统重启后SELinux将恢复为强制模式，除非您修改了/etc/selinux/config文件"
                else
                    # 在交互式环境中询问用户
                    if [ -t 0 ]; then
                        read -p "是否临时将SELinux设置为宽容模式以继续安装? (y/n): " selinux_choice
                        if [ "$selinux_choice" = "y" ] || [ "$selinux_choice" = "Y" ]; then
                            log "临时设置SELinux为宽容模式..."
                            setenforce 0
                            log "SELinux已设置为宽容模式，安装将继续"
                            log "注意: 系统重启后SELinux将恢复为强制模式，除非您修改了/etc/selinux/config文件"
                        else
                            log "继续安装，但可能会遇到SELinux相关的权限问题"
                        fi
                    else
                        # 非交互式环境，默认继续但记录警告
                        log "非交互式环境: 继续安装，但可能会遇到SELinux相关的权限问题"
                        log "提示: 可以使用 'AUTO_SELINUX_PERMISSIVE=true ./elk_deploy.sh' 或 './elk_deploy.sh --selinux-permissive' 自动设置SELinux为宽容模式"
                    fi
                fi
            fi
            
            log "SELinux配置完成"
        fi
    else
        log "未检测到SELinux工具，跳过SELinux配置"
    fi
    
    log "系统检查完成"
}

# 主函数
main() {
    log "开始部署ELK堆栈..."
    
    # 检查系统要求
    check_system_requirements "$1"
    
    # 安装Java环境
    install_java
    
    # 创建数据目录
    setup_data_dirs
    
    # 安装Elasticsearch
    install_elasticsearch
    
    # 安装Logstash
    install_logstash
    
    # 安装Kibana
    install_kibana
    
    # 安装Filebeat
    install_filebeat
    
    # 配置防火墙
    configure_firewall
    
    # 验证ELK部署
    verify_elk
    
    log "ELK堆栈部署完成!"
}

# 执行主函数
main "$1"